package com.wing.product.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wing.common.utils.JsonResult;
import com.wing.common.utils.UniqueIdGeneratorUtil;
import com.wing.product.dao.*;
import com.wing.product.model.entity.*;
import com.wing.product.model.response.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class WarehouseProductInventoryServiceImpl extends ServiceImpl<WarehouseProductInventoryDao, WarehouseProductInventory> implements WarehouseProductInventoryService{

    @Autowired
    WarehouseProductDao warehouseProductDao;
    @Autowired
    WarehouseCustomersInfoDao warehouseCustomersInfoDao;
    @Autowired
    WarehouseStorageOrderDetailDao warehouseStorageOrderDetailDao;
    @Autowired
    WarehouseOutboundRecordDetailDao warehouseOutboundRecordDetailDao;
    @Autowired
    WarehouseProductInventoryTypeDao warehouseProductInventoryTypeDao;
    @Autowired
    WarehouseMaterialRequisitionRecordDao warehouseMaterialRequisitionRecordDao;
    @Autowired
    WarehouseOutboundOrderDetailDao warehouseOutboundOrderDetailDao;
    @Autowired
    WarehouseProductInventoryDao warehouseProductInventoryDao;
    @Autowired
    WarehouseSignOrderDao warehouseSignOrderDao;
    @Autowired
    WarehouseProductMarkDao warehouseProductMarkDao;

    @Override
    public  List<WarehouseProductInventoryVO> selectCount(List<Long> ids,String productId) {
        return baseMapper.selectCount(ids,productId);
    }

    @Override
    public  List<WarehouseProductInventoryVO> selectInventory(List<Long> ids,String productId) {
        return baseMapper.selectInventory(ids,productId);
    }

    @Override
    public Page<WarehouseProductInventoryVO> list4app(Page pg, Map paramMap) {
        List<WarehouseProductInventoryVO> list = baseMapper.list4app(pg, paramMap);
        pg.setRecords(list);
        return pg;
    }

    @Override
    public JsonResult<List<WarehouseProductInventoryVO>> selectProduct(String spaceId, String productId,List<String> bundleCodeList){
        List<WarehouseProductInventoryVO> warehouseProductInventoryVOList = new ArrayList<>();
        //查询产品明细为入库状态
        LambdaQueryWrapper<WarehouseProductInventory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(WarehouseProductInventory::getWarehouseProductId,productId)
                .eq(WarehouseProductInventory::getWarehouseShelfSpaceId,spaceId)
                .eq(WarehouseProductInventory::getIsDeleted,0)
                .eq(WarehouseProductInventory::getProductStatus,3);
        if (CollectionUtils.isNotEmpty(bundleCodeList)){
            lambdaQueryWrapper.notIn(WarehouseProductInventory::getSysBundleCode,bundleCodeList);
        }
        List<WarehouseProductInventory> warehouseProductInventories = this.baseMapper.selectList(lambdaQueryWrapper);

        //通过产品id查询产品类型价格
        WarehouseProductVO warehouseProductVO = warehouseProductDao.selectProductPrice(productId);
        for (WarehouseProductInventory pi : warehouseProductInventories){
            pi.setPrice(warehouseProductVO.getPrice());
            WarehouseProductInventoryVO wpi = new WarehouseProductInventoryVO();
            CopyOptions copyOptions = CopyOptions.create()
                    .setEditable(WarehouseProductInventoryVO.class)
                    .setIgnoreError(true)
                    .setIgnoreNullValue(true);
            BeanUtil.copyProperties(pi, wpi, copyOptions);
            wpi.setIndate(pi.getFirstEntryDate());
            wpi.setProductBrand(warehouseProductVO.getProductBrand());
            wpi.setProductBrandId(warehouseProductVO.getProductBrandId());
            wpi.setProductMark(warehouseProductVO.getProductMark());
            wpi.setProductMarkId(warehouseProductVO.getProductMarkId());
            wpi.setProductProducer(warehouseProductVO.getProductProducer());
            wpi.setProductProducerId(warehouseProductVO.getProductProducerId());
            wpi.setProductVariety(warehouseProductVO.getProductVariety());
            wpi.setProductVarietyId(warehouseProductVO.getProductVarietyId());
            wpi.setProductType(warehouseProductVO.getProductType());
            warehouseProductInventoryVOList.add(wpi);
        }
        return JsonResult.success(warehouseProductInventoryVOList);
    }

    @Override
    public List<WarehouseProductInventoryVO> selectProductDetail(String outboundOrderId){
        LambdaQueryWrapper<WarehouseOutboundOrderDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(WarehouseOutboundOrderDetail::getWarehouseOutboundOrderId,outboundOrderId)
//                .eq(WarehouseOutboundOrderDetail::getStatus,1)
                .eq(WarehouseOutboundOrderDetail::getIsDeleted,0);
        List<WarehouseOutboundOrderDetail> warehouseOutboundOrderDetailList = warehouseOutboundOrderDetailDao.selectList(lambdaQueryWrapper);
        List<Long> longList = warehouseOutboundOrderDetailList.stream().map(WarehouseOutboundOrderDetail::getProductId).collect(Collectors.toList());
        List<WarehouseProductInventoryVO> warehouseProductInventoryVOList = warehouseProductInventoryDao.selectProductDetailInventory(longList);
        return warehouseProductInventoryVOList;
    }

    @Override
    public List<WarehouseProductInventoryVO> selectProductDetailOut(String outboundOrderId){
        LambdaQueryWrapper<WarehouseOutboundOrderDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(WarehouseOutboundOrderDetail::getWarehouseOutboundOrderId,outboundOrderId)
                .eq(WarehouseOutboundOrderDetail::getStatus,1)
                .eq(WarehouseOutboundOrderDetail::getIsDeleted,0);
        List<WarehouseOutboundOrderDetail> warehouseOutboundOrderDetailList = warehouseOutboundOrderDetailDao.selectList(lambdaQueryWrapper);
        List<Long> longList = warehouseOutboundOrderDetailList.stream().map(WarehouseOutboundOrderDetail::getProductId).collect(Collectors.toList());
        List<WarehouseProductInventoryVO> warehouseProductInventoryVOList = warehouseProductInventoryDao.selectProductDetailInventory(longList);
        return warehouseProductInventoryVOList;
    }

    @Override
    public List<WarehouseProductInventoryVO> findByShipmentOrderDetailId(String warehouseShipmentOrderDetailId) {
        return baseMapper.findByShipmentOrderDetailId(warehouseShipmentOrderDetailId);
    }

    @Override
    public Integer queryUserBundleCode(List<String> userBundleCodes) {
        return baseMapper.queryUserBundleCode(userBundleCodes);
    }

    @Override
    public List<WarehouseProductInventory> getAllProductInventory() {
        return baseMapper.selectList(new LambdaQueryWrapper<WarehouseProductInventory>()
                .eq(WarehouseProductInventory::getIsDeleted,0)
                .eq(WarehouseProductInventory::getProductStatus,3));
    }

    @Override
    public JsonResult<Map<String,Object>> selectRanking(){
        List<WarehouseCustomersInfoVO> warehouseCustomersInfoVOS = warehouseCustomersInfoDao.selectAll();
        Map<String,Object> warehouseCustomersInfo = new HashMap<>();
        warehouseCustomersInfo.put("warehouseCustomersInfoVOS",warehouseCustomersInfoVOS);
        warehouseCustomersInfo.put("totalUser",warehouseCustomersInfoVOS.size());

        warehouseCustomersInfo.put("countSettled",warehouseSignOrderDao.countSettled());
        warehouseCustomersInfo.put("countShipment",warehouseSignOrderDao.countShipment());

        if (CollectionUtils.isNotEmpty(warehouseCustomersInfoVOS)){
            List<Long> customersIdList = warehouseCustomersInfoVOS.stream().map(WarehouseCustomersInfoVO::getId).collect(Collectors.toList());
            LambdaQueryWrapper<WarehouseProductInventory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(WarehouseProductInventory::getIsDeleted,0)
                    .in(WarehouseProductInventory::getCustomerId,customersIdList);
            List<WarehouseProductInventory> warehouseProductInventories = this.baseMapper.selectList(lambdaQueryWrapper);
            Integer sum = 0;
            for (WarehouseCustomersInfoVO civ : warehouseCustomersInfoVOS){
                Integer total = 0;
                for (WarehouseProductInventory pi : warehouseProductInventories){
                    if (civ.getId().equals(pi.getCustomerId())){
                        if(pi.getQuantity() != null){
                            sum += pi.getQuantity();
                            total += pi.getQuantity();
                        }
                    }
                }
                civ.setTotalProductInventory(total);
            }
            warehouseCustomersInfo.put("sumProductInventory",sum);
        }
        warehouseCustomersInfoVOS.sort(Comparator.comparingInt(WarehouseCustomersInfoVO::getTotalProductInventory).reversed());

        //安全生产天数
        LambdaQueryWrapper<WarehouseMaterialRequisitionRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WarehouseMaterialRequisitionRecord::getIsDeleted,0)
                        .orderByAsc(WarehouseMaterialRequisitionRecord::getCreateTime);
        List<WarehouseMaterialRequisitionRecord> warehouseMaterialRequisitionRecords = warehouseMaterialRequisitionRecordDao.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(warehouseMaterialRequisitionRecords)){
            // 获取第一条数据的创建时间
            LocalDateTime createTime = warehouseMaterialRequisitionRecords.get(0).getCreateTime();

            // 获取当前时间
            LocalDateTime now = LocalDateTime.now();
            // 计算时间差值
            Duration duration = Duration.between(createTime, now);
            long daysDifference = duration.toDays();       // 差值（天）
            warehouseCustomersInfo.put("safeDays",daysDifference);
        }

        return JsonResult.success(warehouseCustomersInfo);
    }

    @Override
    public JsonResult<Map<Object, Object>> selectInventorySum(){

        Map<Object,Object> inMap = new HashMap<>();

        LambdaQueryWrapper<WarehouseProductInventory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(WarehouseProductInventory::getIsDeleted,0)
                .eq(WarehouseProductInventory::getProductStatus,3);
        List<WarehouseProductInventory> warehouseProductInventories = this.baseMapper.selectList(lambdaQueryWrapper);
        List<String> sysList = warehouseProductInventories.stream().map(WarehouseProductInventory::getUserBundleCode).collect(Collectors.toList());
        List<String> markList = warehouseProductInventories.stream().map(WarehouseProductInventory::getWarehouseProductMark).collect(Collectors.toList());
        //统计日入库,出库
        if (CollectionUtils.isNotEmpty(sysList)){
            LambdaQueryWrapper<WarehouseStorageOrderDetail> lambdaQueryWrapperSod = new LambdaQueryWrapper<>();
            lambdaQueryWrapperSod.eq(WarehouseStorageOrderDetail::getIsDeleted,0)
                    .in(WarehouseStorageOrderDetail::getUserBundleCode,sysList);
            List<WarehouseStorageOrderDetail> warehouseStorageOrderDetailList = warehouseStorageOrderDetailDao.selectList(lambdaQueryWrapperSod);
            Integer sumStorageOrder = 0;
            Integer sumOutboundRecord = 0;
            for (WarehouseStorageOrderDetail so : warehouseStorageOrderDetailList){
                if (so.getCreateTime().toLocalDate().equals(LocalDateTime.now().toLocalDate())){
                    sumStorageOrder++;
                }
            }
            inMap.put("sumStorageOrder",sumStorageOrder);

            LambdaQueryWrapper<WarehouseOutboundRecordDetail> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(WarehouseOutboundRecordDetail::getIsDeleted,0)
                    .in(WarehouseOutboundRecordDetail::getSysBundleCode,sysList);
            List<WarehouseOutboundRecordDetail> warehouseOutboundRecordDetailList = warehouseOutboundRecordDetailDao.selectList(queryWrapper);
            for (WarehouseOutboundRecordDetail ob : warehouseOutboundRecordDetailList){
                if (ob.getCreateTime().toLocalDate().equals(LocalDateTime.now().toLocalDate())){
                    sumOutboundRecord++;
                }
            }
            inMap.put("sumOutboundRecord",sumOutboundRecord);
        }else {
            inMap.put("sumStorageOrder",0);
            inMap.put("sumOutboundRecord",0);
        }

        Integer sumInventory = warehouseProductInventories.size();
        int i;
        Map<String,WarehouseProductMarkVO> markMap = new HashMap<>();
//        List<WarehouseProductInventoryTypeVO> warehouseProductInventoryTypeVOS = warehouseProductInventoryTypeDao.selectInventorySum(markList);
        List<WarehouseProductMarkVO> warehouseProductMarkVOList = warehouseProductMarkDao.selectInventorySum(markList);
        if (CollectionUtils.isNotEmpty(warehouseProductMarkVOList)){
            Integer sumTypeList = 0;
            Double d  = 0.0;

            for (WarehouseProductMarkVO wp : warehouseProductMarkVOList){
                d += wp.getSumMarkNumber().doubleValue()/sumInventory.doubleValue();
                sumTypeList += wp.getSumMarkNumber();
                wp.setPercentage(wp.getSumMarkNumber().doubleValue()/sumInventory.doubleValue());
                markMap.put(wp.getMarkName(),wp);
            }
            WarehouseProductMarkVO warehouseProductMarkVO = new WarehouseProductMarkVO();
            warehouseProductMarkVO.setPercentage(1-d);
            warehouseProductMarkVO.setSumMarkNumber(sumInventory-sumTypeList);
            warehouseProductMarkVO.setMarkName("其他");
            markMap.put("otherTotal",warehouseProductMarkVO);
            inMap.put("markMap",markMap);
//            inMap.put("other",1-d);
//            inMap.put("total",sumInventory-sumTypeList);
//            for (i = 0 ; i< warehouseProductInventoryTypeVOS.size() ; ++i){
//                if (i<=2){
//                    d = warehouseProductInventoryTypeVOS.get(i).getSumType().doubleValue()/sumInventory.doubleValue();
//                    warehouseProductInventoryTypeVOS.get(i).setPercentage(d);
//                    inMap.put(i,warehouseProductInventoryTypeVOS.get(i));
//                }else {
//                    sumTypeList += warehouseProductInventoryTypeVOS.get(i).getSumType();
//                }
//            }
//            if (sumTypeList != 0){
//                d = sumTypeList.doubleValue()/sumInventory.doubleValue();
//                inMap.put(3,d);
//            }
        }
        return JsonResult.success(inMap);
    }

    @Override
    public JsonResult<Map<Object, Object>> selectInventoryTrend(){

        LambdaQueryWrapper<WarehouseProductInventory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(WarehouseProductInventory::getIsDeleted,0);
        List<WarehouseProductInventory> warehouseProductInventories = this.baseMapper.selectList(lambdaQueryWrapper);
        LocalDate today = LocalDate.now();
        LocalDate sevenDaysAgo = today.minusDays(6);

        // 定义日期格式化器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        // 使用年月日格式作为key
        Map<String, Long> dateCountMap = warehouseProductInventories.stream()
                .filter(inventory -> !inventory.getCreateTime().toLocalDate().isBefore(sevenDaysAgo)
                        && !inventory.getCreateTime().toLocalDate().isAfter(today))
                .collect(Collectors.groupingBy(
                        inventory -> inventory.getCreateTime().format(formatter), // 将LocalDateTime格式化为年月日
                        TreeMap::new,
                        Collectors.counting()
                ));

        // 填充缺失的日期，确保前七天都有值
        for (LocalDate date = sevenDaysAgo; !date.isAfter(today); date = date.plusDays(1)) {
            String formattedDate = date.format(formatter);
            dateCountMap.putIfAbsent(formattedDate, 0L);
        }

        return JsonResult.success(dateCountMap);
    }

    @Override
    public List<WarehouseProductInventoryVO> selectMaterialDetail(List<String> materialNumberList){
//        String[] split = materialNumber.split(",");
//        List<String> sysList = Arrays.stream(split).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(materialNumberList)){
           return this.baseMapper.selectMaterialDetail(materialNumberList);
        }else {
            return null;
        }
    }

    @Override
    public List<MoveInventoryVO> factoryList() {
        return baseMapper.factoryList();
    }

    @Override
    public List<MoveInventoryVO> areaList(String warehouseId) {
        return baseMapper.areaList(warehouseId);
    }

    @Override
    public List<MoveInventoryVO> spaceList(String warehouseAreaId) {
        return baseMapper.spaceList(warehouseAreaId);
    }

    @Override
    @Transactional
    public Boolean review(Long id, Long signId) {
        WarehouseProductInventory warehouseProductInventory = baseMapper.findByInventoryId(id);
        warehouseProductInventory.setIsReview(1L);
        warehouseProductInventory.setReviewTime(LocalDateTime.now());
        warehouseProductInventory.setProductStatus(3);
        warehouseProductInventory.setFirstEntryDate(LocalDateTime.now());
        baseMapper.updateById(warehouseProductInventory);

        WarehouseSignOrder warehouseSignOrder1 = warehouseSignOrderDao.selectById(signId);
        warehouseSignOrder1.setPriceTime(LocalDateTime.now());
        warehouseSignOrderDao.updateById(warehouseSignOrder1);

        List<Map> list=baseMapper.findAllIsReview(signId);
        if(list.size()==0){
            WarehouseSignOrder warehouseSignOrder = warehouseSignOrderDao.selectById(signId);
            warehouseSignOrder.setStatus(5);
            warehouseSignOrderDao.updateById(warehouseSignOrder);
        }
        return true;
    }

    @Override
    public WarehouseProductInventoryVO selectByInventoryId(String id) {
        return baseMapper.selectByInventoryId(id);
    }

    @Override
    public JsonResult update(WarehouseProductInventoryVO warehouseProductInventoryVO) {
        WarehouseProductInventory warehouseProductInventory = new WarehouseProductInventory();
        CopyOptions copyOptions = CopyOptions.create()
                .setEditable(WarehouseProductInventory.class)
                .setIgnoreError(true)
                .setIgnoreNullValue(true);
        BeanUtil.copyProperties(warehouseProductInventoryVO, warehouseProductInventory,copyOptions);
        warehouseProductInventory.setWarehouseProductVariety(warehouseProductInventoryVO.getProductVarietyId().toString());
        warehouseProductInventory.setProduct_producer_id(Integer.parseInt(warehouseProductInventoryVO.getProductProducerId()));
        baseMapper.updateById(warehouseProductInventory);

        return null;
    }

    @Override
    public WarehouseProductInventoryProcessVO selectInventoryProcess(String id) {
        WarehouseProductInventoryProcessVO warehouseProductInventoryProcessVO=baseMapper.selectInventoryInfo(id);

        warehouseProductInventoryProcessVO.setShipmentList(baseMapper.findInventoryShipment(id));

        warehouseProductInventoryProcessVO.setSignList(baseMapper.findInventorySign(id));
        warehouseProductInventoryProcessVO.setMoveList(baseMapper.findInventoryMove(id));
        warehouseProductInventoryProcessVO.setTransferList(baseMapper.findInventoryTransfer(id));
        warehouseProductInventoryProcessVO.setOutboundList(baseMapper.findInventoryOutbound(id));
        return warehouseProductInventoryProcessVO;
    }
}
